#!/bin/bash
#
# hzclish - Hubzilla (ex Red Matrix) cli bash script.
# Version 1.2 (legacy. Wont be updated)
# Source: https://notabug.org/uzver/hzclish
#
# License: WTFPL2 http://wtfpl2.com/
# uzver(at)protonmail.ch
#
# Deps: curl, jq, markdown or pandoc or discount, grep, sed, awk, tr, mkdir, mktemp, rm, wc, which

thispath="$(realpath $0)"
thisdir="$(dirname "$thispath")"
dotdir=~/'.hzclish'
verbose=0
ssl=1
markdown='markdown'
useragent='Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0'

# FUNCTIONS

USAGE(){
    exec=$(basename "$0"); [[ "$exec" ]] || exec="${0##*/}"
    cat << EOF
  $exec - CLI bash wrapper script for the Hubzilla (Red Matrix) twitter API.

  USAGE: $exec [OPTIONS] [-u LOGIN:DOMAIN[:PASSWORD]] [<<<"MESSAGE"]
    
  OPTIONS:
    -c config                   Specify config file.
                                 (use different configs for different accounts).
    -d                          Set config file as default auth (requires: -s|-g|-p).
    -D                          Delete config and cookie files.
    -g ID                       Get post of given ID.
    -h, --help                  Show this help.
    -i                          Post from standart input.
    -m <str>                    Set your custom markdown engine (overwrites: -P).
    -p                          Post the message.
    -P                          Use pandoc instead of markdown
                                 (it's short for:
                                   -m "pandoc -f markdown_strict+footnotes+definition_lists+hard_line_breaks -t html").
    -q                          Less verbose printing.
    -R                          Renew auth token.
    -s                          Set new authentification (save login, password).
    -S yes|no                   Use or not https (default: yes) (useful for inline auth: -u).
    -t                          Convert very last line (of your post) with hashtags to categories,
                                 and post with the same hashtags and categories.
    -T                          Convert very last line (of your post) with hashtags to categories,
                                 and drop hashtags. Post only with categories.
    -u LOGIN:DOMAIN[:PASSWORD]  Specify auth inline, e.g.:
                                 "inbox@example.com:hubdomain.com:password",
                                 or:
                                  "channelname@hubdomain.com:password", or:
                                  "channelname@hubdomain.com"
                                 (use it if you do not want to save auth)
                                 (implies not to use with: -c, -D, -r, -s).
    -v                          Verbose mode.
    
    Notice: For now length of message limited by bash variable size limit.

  EXAMPLES:
    Save new authentification to config file and set it default:
      $exec -s
     or save new auth and set it default:
      $exec -vds                               # verbose
     or to custom place or name:
      $exec -vc ~/myConfig -s                  # save to myConfig file in home
                                                  directory
      $exec -vc myConfig -s                    # save to "$dotdir"/myConfig file
     or to custom place or name and set default:
      $exec -vdc ~/myConfig -s                 # save to myConfig file in home
                                                  directory
      $exec -vdc myConfig -s                   # save to "$dotdir"/myConfig file

    Post message:
      $exec
      $exec -vp
      $exec -c myConfig                        # with custom config
      $exec -dc myNewDefaultConfig             # with custom config & set it
                                                default
    Post message from stdin:
      $exec <<<"Hello world!"
      echo "Hello world!" | $exec
      cat myPost.md | $exec

    Read post by id:
      $exec -g 1234567
      $exec -qg 1234567
      $exec -c myConfig -g 1234567             # with custom config
      $exec -dc myNewDefaultConfig -g 1234567  # with custom config & set it
                                                  default
EOF
}

CONFIG(){
    # Check for config file and create new one if it does not exist
    if ! (($custconfig)) && ! (($setnew)); then
        confdir="$dotdir"
        if  [[ -f "${confdir}/defaultconfig" ]]; then
            source "${confdir}/defaultconfig"
        else
            echo -e '\e[37;31m'"\e[1m[error]\e[0m" "Can't find defaultconfig" >&2
            exitstatus=1
        fi
    else
        ! (($quiet)) && (($verbose)) && [[ $config ]] && echo -e "\e[0;36m""Using config: $config""\e[m"
        # Find directory of config file if '$config' is file and set it as config directory '$confdir'
        [[ -f "$config" ]] && confdir=$(dirname "$config")
        # In case '$config' is zid:
        #  set config directory to script dot directory '$dotdir'
        [[ -d "$confdir" ]] || confdir="$dotdir"
        # Create path to config file and set it as '$config'
        if [[ -f "$config" ]]; then
            true
        else
            if [[ -f "${confdir}/$config" ]]; then
                config="${confdir}/$config"
            elif [[ -f "${confdir}/${config}.config" ]]; then
                config="${confdir}/${config}.config"
            fi
        fi
# echo confdir "$confdir"
# echo config "$config"
# exit
    fi

    if [[ -f "$config" ]]; then
        ! (($quiet)) && (($verbose)) && echo -e "\e[0;36m""Using config: $config""\e[m"
        # (($custconfig)) && confdir=$(dirname "$config")
        if (($setdefconf)); then
            ! (($quiet)) && (($verbose)) && echo -e "\e[0;36m""Setting default config to: $config""\e[m"
            echo "config=\"$config\"">"${confdir}/defaultconfig" && [[ -f "${confdir}/defaultconfig" ]] && chmod 600 "${confdir}/defaultconfig"
        fi
    else
        mkdir -p "$confdir" && chmod 700 "$confdir"
        echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "Creating new config file:"
        read -p "Enter hub domain (example.com): " domain
        domain=$(echo "${domain%/*}" | sed 's|^[[:space:]]*https\?://||g')
        if ! (($sslsetted)); then
            validsslres=0
            sslres=y
            while ! (($validsslres)); do
                read -n 1 -p "Does your hub use SSL? (Y/n): " sslres
                if [[ "${sslres,,}" == [Nn] ]]; then
                    validsslres=1
                    ssl=0
                    hub="http://$domain"
                elif [[ "${sslres,,}" == [Yy] || -z "$sslres" ]]; then
                    validsslres=1
                    ssl=1
                    hub="https://$domain"
                else
                    validsslres=0
                    echo -e "\e[0;31m\nResponse not valid, please answer y or n\e[m"
                fi
            done
            echo
        fi
        if (($ssl)); then
            hub="https://$domain"
        else
            hub="http://$domain"
        fi
        read -p "Enter login e-mail: " login
        read -p "Enter nickname (channel nickname) (or leave blank): " channel
        if [[ "$channel" ]]; then
            zid="${channel}@$domain"
        elif [[ "$login" ]]; then
            zid="${login}@$domain"
        fi
        if ! [[ "$login" ]]; then
            echo 'Please specify login'
            (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
            exit 1
        fi
        if ! (($custconfig)); then
            config="${confdir}/${zid}.config"
        fi
        # if [[ "$(grep 'token=.\+' "$config")" ]]; then
        [[ -f "$config" ]] && source "$config"
        if [[ "$token" ]]; then
            echo -e '\e[37;31m'"\e[1m[error]\e[0m" "Script appears to be registered previously" >&2
            echo "        Use: "$exec" '-D ${zid}' to delete auth and then '-s' option to try again" >&2
            (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
            exit 1
        fi
        if (($setdefconf)) || [[ ! -f "${confdir}/defaultconfig" || "$(wc -m "${confdir}/defaultconfig"|cut -d ' ' -f 1)" == 0 ]]; then
            ! (($quiet)) && (($verbose)) && echo -e "\e[0;36m""Setting default config to: $config""\e[m"
            echo "config=\"$config\"">"${confdir}/defaultconfig" && [[ -f "${confdir}/defaultconfig" ]] && chmod 600 "${confdir}/defaultconfig"
        fi
        cookie="${zid}.cookie"
{
cat << EOF
hub="$hub"
login="$login"
channel="$channel"
zid="$zid"
useragent="$useragent"
cookie="\${zid}.cookie"
EOF
}>"$config"
        [[ -f "$config" ]] && chmod 600 "$config"
        if ! (($quiet)) && (($verbose)); then
            echo -e "\e[0;36m""These variables have been saved to ${config}:""\e[m"
            echo -e "\e[0;36m"; cat "$config"; echo -e "\e[m"
        fi
    fi
    source "$config"
    # scookie="${confdir}/${zid}.cookie"
    [[ -f "${confdir}/${zid}.cookie" ]] || (touch "${confdir}/${zid}.cookie" && chmod 600 "${confdir}/${zid}.cookie")

    if [[ "$(which jq >& /dev/null; echo $?)" == 0 ]]; then
        jq="jq"
    elif [[ -f ~/"bin/jq" ]]; then
        jq=~/"bin/jq"
    elif [[  -f "${thisdir}/jq" ]]; then
        jq="jq"
    elif [[ -f "${confdir}/jq" ]]; then
        jq="jq"
    elif [[ -f "${dotdir}/jq" ]]; then
        jq="jq"
    fi
}

PASSWORD(){
unset password
if [[ "$config" ]] && [[ "$(grep 'password=' "$config")" ]]; then
    source "$config"
else
    echo ""
    prompt="What is your password?: "
    while IFS= read -p "$prompt" -r -s -n 1 char
    do
        if [[ $char == $'\0' ]]; then
            break
        fi
            prompt='*'
            password+="$char"
    done
    echo -e "\n"
fi
}

SETAUTH(){
    CONFIG
    source "$config"
    if ! [[ "$password" ]]; then
        echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "This is the only time you asked for your password"
        echo "Your password will be stored plain in config file"
        PASSWORD
    fi
    sed -i '/password=/d' "$config"
    echo password=\"$(sed 's/\"/\\"/g'<<<"$password")\">>"$config"
    if (($verbose)); then
        echo -e "\e[0;36m""Password have been saved to $config""\e[m"
    fi
    
    source "$config"
    echo "Getting token..."
    getauth=$(curl -ksSi --trace-ascii - -u "${login}:${password}" \
     -H "User-Agent: $useragent" \
    "${hub}/api/account/verify_credentials" \
     --cookie-jar "${confdir}/$cookie" --cookie "${confdir}/$cookie")
    token=$(echo "$getauth"|sed -n 's/^.*[aA]uthorization: [Bb]asic \(.*\)/\1/p1')

    # unset getauth
    if [[ "$token" ]]; then
        sed -i '/token=/d' "$config"
        echo "token=\"${token}\"">>"$config"
        # unset token
        if (($verbose)); then
            echo -e '\e[37;32m'"\e[1m[success]\e[0m" "Token saved"
        fi
    else
        echo -e '\e[37;31m'"\e[1m[error]\e[0m" "Getting token failed. Check/set your login/password/connection"
(($verbose)) && echo -e '\e[37;31m'"\e[1m[post]\e[0m" && echo "$getauth"
        unset getauth
        (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
        exitstatus=1
    fi

    local error=''
    error=$(echo "$getauth" | grep -io '^This api requires login')
    [[ "$error" ]] || error=$(echo "$getauth" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
    if [[ "$error" ]]; then
        [[ "$token" ]] && echo 'but'
        unset token
        echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
        echo "Check/set your login/password/server and try again"
        (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
        exitstatus=1
    fi

    if (($exitstatus)); then
        (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
        exit $exitstatus
    fi
}

RETOKEN(){
    CONFIG
    source "$config"
    while [[ ! $retokened ]]; do
        if ! (($quiet)) && (($verbose)); then
            echo -e "\e[0;36m""Getting new token...""\e[m"
        fi
        if ! [[ "$password" ]]; then
            PASSWORD
        fi
        getauth=$(curl -ksSi --trace-ascii - -u "${login}:$password" \
         -H "User-Agent: $useragent" \
        "${hub}/api/account/verify_credentials" \
         --cookie-jar "${confdir}/$cookie" --cookie "${confdir}/$cookie")
        body=$(echo -n "$getauth"|grep -iom1 '{\".*[^\]\(["}]\|\]\)}')
        [[ "$body" ]] || body=$(echo -n "$getauth"|grep -i 'error')
        unset password
        token=$(echo "$getauth"|sed -n 's/^.*[aA]uthorization: [Bb]asic \(.*\)/\1/p1')

        # unset getauth
        if [[ "$token" ]]; then
            sed -i '/token/d' "$config"
            echo "token=\"${token}\"">>"$config"
            # unset token
            if (($verbose)); then
                echo -e '\e[37;32m'"\e[1m[success]\e[0m" "Token saved"
            fi
        else
            echo -e '\e[37;31m'"\e[1m[error]\e[0m" "Getting new token failed. Check/set your login/password/server"
(($verbose)) && echo -e '\e[37;31m'"\e[1m[post]\e[0m" && echo "$getauth"
unset getauth
            # (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
            exitstatus=1
        fi

        local error=''
        error=$(echo "$getauth" | grep -io '^This api requires login')
        [[ "$error" ]] || error=$(echo "$getauth" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
        if [[ "$error" ]]; then
            [[ "$token" ]] && echo 'but'
            unset token
            echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
            (($verbose)) && [[ "$body" ]] && echo -en "\e[0;31m" && echo -n "$body" && echo -e "\e[m"
            echo "Check/set your login/password/server"
            # (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
            exitstatus=1
        fi

        if (($exitstatus)); then
            (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
            exit $exitstatus
        fi
        ((retokened++))
    done
}

GETPOST(){
    if ! (($inlineauth)); then
        CONFIG
        source "$config"
        unset password
    fi
    if [[ "$1" ]]; then
        local pid="$1"
    else
        echo 'Please specify the post id'
        (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
        exit 1
    fi
    [[ "$2" == 'urlonly' ]] && local urlonly=1
    local post=''
    GETPOSTINIT(){
        if (($inlineauth)); then
            ! [[ "$password" ]] && PASSWORD
            (($verbose)) && echo -e "\e[0;36m""Getting post $pid...""\e[m"
            post=$(
                curl -ksSi -u "${login}:$password" \
                    -H "User-Agent: $useragent" \
                    -H "Content-Type: application/json" \
                    -H 'Accept: application/json' \
                    "${hub}/api/statuses/show.json?id=$pid")
                    # "${hub}/api/z/1.0/item/full?item_id=$pid"
                    # "${hub}/api/z/1.0/item/full?mid=$mid"
            unset password
        else
            (($verbose)) && echo -e "\e[0;36m""Getting post $pid...""\e[m"
            post=$(
                curl -ksSi \
                    -H "Authorization: Basic $token" \
                    -H "User-Agent: $useragent" \
                    -H "Content-Type: application/json" \
                    -H 'Accept: application/json' \
                    "${hub}/api/statuses/show.json?id=$pid" \
                    --cookie-jar "${confdir}/$cookie" --cookie "${confdir}/$cookie")
                    # "${hub}/api/z/1.0/item/full?item_id=$pid"
                    # "${hub}/api/z/1.0/item/full?mid=$mid"
            unset password
            unset token
        fi
        postbody=$(echo -n "$post"|grep -iom1 '{\".*[^\]\(["}]\|\]\)}')
        mid=$(echo -n "$postbody"|"$jq" -r '.message_id')
        posturl=$(echo -n "$postbody"|"$jq" -r '.url')
        posturl2="$(echo -n "$posturl"|sed 's|^.*\(https\?://[^/]\+\)/.*|\1|')/display/$mid"
        if ! (($urlonly)); then
            username=$(echo -n "$postbody"|"$jq" -r '.user.screen_name')
            userurl=$(echo -n "$postbody"|"$jq" -r '.user.url')
            userhub=$(echo "$userurl"|sed 's|^.*https\?://\([^/]\+\)/.*|\1|')
            posttxt=$(echo -n "$postbody"|"$jq" -r '.text')
        fi
    }
    GETPOSTINIT
    local error=''
    error=$(echo "$post" | grep -io '^This api requires login')
    [[ "$error" ]] || error=$(echo "$post" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
    if [[ "$error" ]]; then
        if [[ $retokened != 1 ]] && [[ $inlineauth != 1 ]]; then
            if ! (($quiet)); then
                # echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
                # echo -e '\e[37;32m'"\e[1m[warning] \e[0m" "$error"
                echo -en "\e[0;33m[warning] \e[m"; echo "$error"
                echo "Error or invalid token, requesting new one..."
            fi
            RETOKEN
            GETPOSTINIT
            local error=''
            error=$(echo "$post" | grep -io '^This api requires login')
            [[ "$error" ]] || error=$(echo "$post" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
            if [[ "$error" ]]; then
                echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
                echo "Can't get post due authorization issue"
                echo "Check/set your login/password/server and try to get post again"
                (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
                exit 1
            fi
        else
            echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
            echo "Can't get post due authorization issue"
            echo "Check/set your login/password/server and try to get post again"
            (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
            exit 1
        fi
    fi

    if [[ "$mid" ]]; then
        if ! (($urlonly)); then
            echo -e "\e[0;36m""${username}@${userhub}:""\e[m\n"
            echo "$posttxt"
            if ! (($quiet)); then
                echo -e "\n\e[0;36m""post url: $posturl2""\e[m"
            fi
        else
            echo -e "\n\e[0;36m""$posturl2""\e[m"
        fi
    else
        echo -e '\e[37;31m'"\e[1m[error]\e[0m" "No post returned, please try again or give up"
(($verbose)) && echo -e '\e[37;31m'"\e[1m[post]\e[0m" && echo "$post"
        (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
        exit 1
    fi
}

POST(){
    if ! (($inlineauth)); then
        CONFIG
        source "$config"
        unset password
    fi
    if ! (($hasmsg)); then
        local postfile=$(mktemp /tmp/hzpost.XXXXXX)
        local message=$(mktemp /tmp/hzmessage.XXXXXX)
    else
        local postfile="$postfile"
        local message="$message"
# echo HAS MESSAGE
# echo
# echo verbose "$verbose"
# echo hasmsg "$hasmsg"
# echo postfile "$postfile"
# echo message "$message"
# echo tagline "$tagline"
# echo tags "$tags"
# echo catline "$catline"
# cat "$message"
# exit
    fi
    [[ -f "$message" && -f "$postfile" ]] && chmod 600 "$postfile" "$message"
    local post=''
    local pid=''
    POSTINIT(){
        if ! (($hasmsg)); then
            if ! [[ -t 0 ]] || (($stdin)); then
                eval 'stdin=$(cat); echo "$stdin"' >"$message"
            else
                $EDITOR "$message"
            fi
            msglength=$(wc -m "$message"|cut -d ' ' -f 1)
            if ! (($msglength)); then
                echo -e '\e[37;31m'"\e[1m[error]\e[0m" "The message is empty. Not posting message"
                echo "Not deleting the file \"$message\" in case it is not empty"
                /bin/rm -f "$postfile"
                (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
                exit 1
            fi
            ## Delete leading blank lines
            sed -i '/./,$!d' "$message"

            msglines=$(wc -l "$message"|cut -d ' ' -f 1)
        fi
        # Make tags only if message length more than 1 line
        if [[ ! "$tagline" ]] && [[ "$msglines" -gt 1 ]]; then
            tagline=$(tail -n 1 "$message" | grep -io '^[[:space:]]*\?\#.*\?')
             [[ "$tagline" ]] && hastagline="$tagline"
            ! (($catonly)) && tags=$(echo "$tagline" | sed 's|^[[:space:]]*||; s|,||g')
        fi
        if [[ ! "$catline" ]]; then
            catline=$(head -n 1 "$message" | grep -iom1 '^[[:space:]]*\?\*.*\?')
            [[ "$catline" ]] && hascatline=1
            (($tagtocat)) && catline=$(echo "$tagline" | sed 's|^[[:space:]]*\?\#|\*|g; s|[[:space:]]*\?\#| \*|g')
        fi
        catsarr=($(echo "$catline" | sed 's|[\*]| |g; s|^[[:space:]]*||; s|,||g; s/\"/\\"/g'))
        local category=''
        for c in "${catsarr[@]}"; do category+="${c},"; done
        # (($catonly)) && tagline='' && tags=''
# echo verbose "$verbose"
# echo hasmsg "$hasmsg"
# echo postfile "$postfile"
# echo message "$message"
# echo tagline "$tagline"
# echo tags "$tags"
# echo catline "$catline"
# echo catsarr "${catsarr[@]}"
# echo category "$category"
# cat "$message"
# echo
        msg=$(cat "$message")
# echo msg "$msg"
# echo
# echo
        if ! (($catonly)); then
            if [[ "$tagline" || "$hastagline" ]]; then
                msg=$(echo "$msg" | awk -F "$tagline" '{print $1}')
            fi
        else
            tagline='' && tags=''
            [[ "$hastagline" ]] && msg=$(echo "$msg" | awk -F "$hastagline" '{print $1}')
        fi
# echo msg "$msg"
# echo hasmsg $hasmsg
# echo hastagline $hastagline
# echo hascatline $hascatline
# echo catline "$catline"
# exit
        if ! (($hasmsg)) && ! (($tagtocat)) && (($hascatline)); then
            # FIXME: slow part
            [[ "$catline" ]] && msg=$(echo "$msg" | awk -v cl="$catline" '$0 == cl {i=1;next};i && i++ <= 999')
            ## Delete leading blank lines
            sed -i '/./,$!d' "$message"
        fi
        title=$(echo "$msg" | head -n 1 | grep -iom1 '^[[:space:]]*\?\#[[:space:]]\+.*\?' | sed 's/\"/\\"/g; s/^[[:space:]]*\?\#[[:space:]]\+//g')
        [[ "$title" ]] && msg=$(echo "$msg" | sed 1d)
        ## Delete leading blank lines
        sed -i '/./,$!d' "$message"
# echo hasmsg $hasmsg
# echo hastagline $hastagline
# echo hascatline $hascatline
# echo message "$message"
# echo tagline "$tagline"
# echo tags "$tags"
# echo catline "$catline"
# echo catsarr "${catsarr[@]}"
# echo title "$title"
# echo -n 'message '; cat "$message"; echo 
# echo msg "$msg"
# exit
        [[ "$title" ]] && echo "title=\"$title\"">"$postfile"
        [[ "$category" ]] && echo "category=\"${category%,}\"">>"$postfile"
        if (($pandoc)); then
            # markdown="pandoc -f markdown -t html" # (pandoc's extended markdown)
            # markdown="pandoc -f markdown_phpextra -t html" # (PHP Markdown Extra extended markdown)
            # markdown="pandoc -f markdown_github -t html" #  (github  extended  markdown)
            markdown="pandoc -f markdown_strict+footnotes+definition_lists+hard_line_breaks -t html" # (original unextended markdown + with footnotes and definition lists and hard line breaks)
        elif [[ "$mdexec" ]]; then
            markdown="$mdexec"
        fi
        htmlstatus=$(echo -n "$msg" | $markdown | sed 's/\"/\\"/g' | tr -d "\n"; [[ "$tags" ]] && echo "<br><br>$tags" | sed 's/\"/\\"/g' || echo "")
        [[ "$htmlstatus" ]] && echo "htmlstatus=\"$htmlstatus\"">>"$postfile"
# echo msg "$msg"
# exit
        source "$postfile"
# echo " export token='$token'"
# echo " export useragent='$useragent'"
# echo " export hub='$hub'"
# echo " export title='$title'"
# echo " export category='$category'"
# echo " export channel='$channel'"
# echo " export htmlstatus='$htmlstatus'"
# echo " export cookie='$cookie'"
# exit
        if (($inlineauth)); then
            ! [[ "$password" ]] && PASSWORD
            (($verbose)) && echo -e "\e[0;36m""Posting...""\e[m"
            post=$(curl -ksSi \
            -u "${login}:$password" \
            -H "User-Agent: $useragent" \
            -X POST \
            -d "title=${title}&category=$category" \
            --data-urlencode "htmlstatus=$htmlstatus" \
            "${hub}"/api/statuses/update)
            unset password
        else
            (($verbose)) && echo -e "\e[0;36m""Posting...""\e[m"
            post=$(curl -ksSi \
            -H "Authorization: Basic $token" \
            -H "User-Agent: $useragent" \
            -X POST \
            -d "title=${title}&category=${category}&channel=$channel" \
            --data-urlencode "htmlstatus=$htmlstatus" \
            "${hub}"/api/statuses/update \
            --cookie-jar "${confdir}/$cookie" --cookie "${confdir}/$cookie")
            unset password
            unset token
        fi
# echo "$post"
# exit
        postbody=$(echo -n "$post"|grep -iom1 '{\".*[^\]\(["}]\|\]\)}')
        mid=$(echo -n "$postbody"|"$jq" -r '.message_id')
        if [[ "$mid" ]]; then
            posturl=$(echo -n "$postbody"|"$jq" -r '.url')
            posturl2="$(echo -n "$posturl"|sed 's|^.*\(https\?://[^/]\+\)/.*|\1|')/display/$mid"
        fi
        pid=$(echo -n "$postbody"|"$jq" -r '.id')
        username=$(echo -n "$postbody"|"$jq" -r '.user.screen_name')
        userurl=$(echo -n "$postbody"|"$jq" -r '.user.url')
        userhub=$(echo "$userurl" | sed 's|^.*https\?://\([^/]\+\)/.*|\1|')
    }
    POSTINIT
    local error=''
    error=$(echo "$post" | grep -io '^This api requires login')
    [[ "$error" ]] || error=$(echo "$post" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
    if [[ "$error" ]]; then
        if ! (($retokened)) && ! (($inlineauth)); then
            if ! (($quiet)); then
                # echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
                # echo -e '\e[37;32m'"\e[1m[warning] \e[0m" "$error"
                echo -en "\e[0;33m[warning] \e[m"; echo "$error"
                echo "Error or invalid token, requesting new one..."
            fi
            RETOKEN
            POSTINIT
            local error=''
            error=$(echo "$post" | grep -io '^This api requires login')
            [[ "$error" ]] || error=$(echo "$post" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
            if [[ "$error" ]]; then
                echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
                echo "Can't post due authorization issue"
                echo "Check/set your login/password/server and try to post again"
                (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
                exit 1
            fi
        else
            echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
            echo "Can't post due authorization issue"
            echo "Check/set your login/password/server and try to post again"
            (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
            exit 1
        fi
    fi
    
    if [[ "$mid" || "$pid" ]]; then
        if ! (($quiet)); then
            if [[ "$pid" ]]; then
                local id="$pid"
            elif [[ "$mid" ]]; then
                local id="$mid"
            fi
            echo -e '\e[37;32m'"\e[1m[success]\e[0m" "Message "$id" posted"
            echo -en "\e[0;36m""post url: ""\e[m"
# (($verbose)) && echo -e '\e[37;32m'"\e[1m[post]:\n$post\e[0m"
        fi
        if  [[ "$mid" ]]; then
            echo -e "\e[0;36m""$posturl2""\e[m"
        else
            GETPOST "$pid" urlonly
        fi
        /bin/rm -f "$postfile" "$message"
    else
        echo -e '\e[37;31m'"\e[1m[error]\e[0m" "No post id returned, please try again or give up"
(($verbose)) && echo -e '\e[37;31m'"\e[1m[post]:\n" && echo -n "$post" && echo -e "\e[0m"
        echo "Message should still be saved in the file $message"
        /bin/rm -f "$postfile"
        (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
        exit 1
    fi
}

# DELETE CONFIG & COOKIE
DELETE(){
#    [[ "$config" ]] && source "$config" && unset password
#    ! (($quiet)) && echo Deleting: cookie: "${confdir}/${zid}.cookie", config: "$config"
#    [[ "$confdir" && "$zid" ]] && [[ -f "${confdir}/${zid}.cookie" ]] && /bin/rm -f "${confdir}/${zid}.cookie"
#    [[ "$config" ]] && [[ -f "$config" ]] && /bin/rm -f "$config"
    ! (($quiet)) && (($verbose)) && [[ $zid ]] && echo -e "\e[0;36m""Using config: $zid""\e[m"
    # Find directory of config file if '$config' is file and set it as config directory '$confdir'
    [[ -f "$zid" ]] && local confdir=$(dirname "$zid")
    # In case '$config' is zid:
    #  set config directory to script dot directory '$dotdir'
    [[ -d "$confdir" ]] || local confdir="$dotdir"
    # Create path to config file and set it as '$config'
    if [[ -f "$zid" ]]; then
        true
    else
        if [[ -f "${confdir}/${zid}" ]]; then
            local config="${confdir}/$zid"
            local cookie="${confdir}/${zid%.config}.cookie"
        elif [[ -f "${confdir}/${zid}.config" ]]; then
            local config="${confdir}/${zid}.config"
            local cookie="${confdir}/${zid%.config}.cookie"
        fi
    fi
    ! (($quiet)) && echo Deleting cookie: "$cookie"
    [[ -f "$cookie" ]] && /bin/rm -f "$cookie"
    ! (($quiet)) && echo Deleting config: "$config"
    [[ -f "$config" ]] && /bin/rm -f "$config"
}

if [[ $# -lt 1 ]]; then
    exe=1
    POST
elif [[ "$1" == '--help' ]]; then
    USAGE
    exit 0
fi

# RUN OPTIONS
while getopts ":c:d:D:g:him:pPqrsS:tTu:v" OPTION
do
  case $OPTION in
    c)
      if [[ "$OPTARG" ]]; then
        config="$OPTARG"
        custconfig=1
      fi
      ;;
    d)
      #if [[ "$OPTARG" ]]; then
      #  config="$OPTARG"
      #  custconfig=1
      #fi
      setdefconf=1
      ;;
    D)
      exe=1
      zid="$OPTARG"
      DELETE
      ;;
    g)
      exe=1
      pid="$OPTARG"
      GETPOST "$pid"
      # echo "$pid"
      ;;
    h)
      exe=1
      USAGE
      ;;
    i)
      stdin=1
      ;;
    m)
      mdexec="$OPTARG"
      ;;
    p)
      exe=1
      POST
      ;;
    P)
      pandoc=1
      ;;
    q)
      quiet=1
      ;;
    r)
      exe=1
      RETOKEN
      ;;
    s)
      exe=1
      setnew=1
      setdefconf=1
      SETAUTH
      ;;
    S)
      sslarg="$OPTARG"
      if [[ "$sslarg" ]]; then
        if [[ "$sslarg" == [nN][oO] ]]; then
          ssl=0
          sslsetted=1
        elif [[ "$sslarg" == [yY][eE][sS] ]];   then
          ssl=1
          sslsetted=1
        fi
      else
        ssl=1
        sslsetted=1
      fi
      ;;
    t)
      tagtocat=1
      ;;
    T)
      tagtocat=1
      catonly=1
      ;;
    u)
      if [[ "$OPTARG" ]]; then
        # "user@example.com:hubdomain.com:password"
        haspass=$(echo "$OPTARG" | awk -F':' '{print $3}')
        login="${OPTARG%%:*}"
        if [[ "$haspass" ]]; then
          domainandpass="${OPTARG#*:}"
          domain="${domainandpass%%:*}"
          password="${domainandpass#*:}"
          unset haspass
          unset domainandpass
        else
          domain="${OPTARG##*:}"
        fi
        if (($ssl)); then
          hub="https://$domain"
        else
          hub="http://$domain"
        fi
        zid=""
        inlineauth=1
      fi
      ;;
    v)
      verbose=1
      ;;
    \?)
      # echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "Invalid option: -$OPTARG" >&2
      echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "Invalid option" >&2
      (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
      exit 1
      ;;
    :)
      echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "Option -$OPTARG requires an argument" >&2
      (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
      exit 1
      ;;
  esac
done
shift $(($OPTIND -1))
# echo $exe; exit
## Post if no other functional commands was given
if ! (($exe)); then
  exe=1
  POST
fi

exit 0

### TODO:
# message size limit (bash var)
# read post + comments
# read by mid
# private post
# use keyring
# delete post
# comment post
# delete comment
# reshare post
# like, dislike
# attach image to post
# notifications
# debug
# version option
# webdav files
# more errors handle
# >&2
